package util;

import com.aliasi.matrix.CosineDistance;

import java.util.*;

/**
 * @author ：hzs
 * @date ：Created in 2021/4/20 14:28
 * @description：
 * @modified By：
 * @version: $
 */
public class CosineTextSimilarity {

    public static double getSimilarityBetweenTwoSentences(String s1, String s2) {

        List<String> list1 = removeStopWords(s1);
        List<String> list2 = removeStopWords(s2);
        Map<String, Integer> words = new HashMap<>();
        int i = 0;
        for (String s : list1) {
            if (!words.containsKey(s)) {
                words.put(s, i++);
            }
        }
        for (String s : list2) {
            if (!words.containsKey(s)) {
                words.put(s, i++);
            }
        }
        double[] coordinate1 = getCoordinate(list1, words);
        double[] coordinate2 = getCoordinate(list2, words);
        return getDistance(coordinate1, coordinate2);
    }

    private static List<String> removeStopWords(String s) {
        Set<String> stopWords = StopWordUtil.getStopWordsEN();
        List<String> result = new ArrayList<>();
        s = s.toLowerCase();
        String[] split = s.split(" ");
        for (String s1 : split) {
            String s2 = s1.replaceAll("[^0-9^a-z^A-Z^\\-]", "");
            if (!s2.isEmpty() && !stopWords.contains(s2)) {
                result.add(s2);
            }
        }
        return result;
    }

    private static double[] getCoordinate(List<String> list, Map<String, Integer> words) {
        double[] result = new double[words.size()];
        for (int i = 0; i < list.size(); i++) {
            result[words.get(list.get(i))]++;
        }
        return result;
    }

    private static double getDistance(double[] coordinate1, double[] coordinate2) {
        double a = 0;
        double b = 0;
        double c = 0;
        for (int i = 0; i < coordinate1.length; i++) {
            a += coordinate1[i] * coordinate1[i];
            b += coordinate2[i] * coordinate2[i];
            c += coordinate1[i] * coordinate2[i];
        }
        if (a == 0 || b == 0) {
            return -1.0;
        }
        return c / (Math.sqrt(a) * Math.sqrt(b));
    }

    public static void main(String[] args) {
        String s1 = "A class of normal attack relations has been introduced in [23].";
        String s2 = "When introducing preferences between defeasible rules, one key question is whether the introduced preferences are\n" +
                "helpful and sensible.";
        System.out.println(getSimilarityBetweenTwoSentences(s1, s2));
    }

}
